package com.binc.testspring.service.impl.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.binc.testspring.common.annotation.BincLog;
import com.binc.testspring.common.utils.DictUtils;
import com.binc.testspring.common.utils.Global;
import com.binc.testspring.dto.annotation.ContractDto;
import com.binc.testspring.common.excel.EasyExcelWriteUtils;
import com.binc.testspring.service.IExportService;
import com.binc.testspring.util.DateUtil;
import com.binc.testspring.vo.FundNhouseTransFlowVo;
import com.binc.testspring.vo.IdVo;
import com.binc.testspring.vo.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class ExportServiceImpl implements IExportService {

    final static int EXPORT_SIZE = 1000;

    @Override
    public void export(HttpServletResponse response, IdVo idVo) throws IOException {
        log.info("导出 ：条件：【" + idVo + "】");
        // 16070400000 186天，不能在if里面，否则是负数
        Long dayTm = 6 * 31 * 24 * 3600 * 1000L;
        // Assert.notNull(idVo, "查询条件不能全部为空");
        // Assert.notNull(idVo.getId(), "id不能为空");
        // Assert.notNull(idVo.getType(), "type不能为空");

         //设置间隔天数
        // if ((idVo.getCreateEndTime() - idVo.getCreateStartTime()) > dayTm) {
        //     throw new BusinessRtException("选择范围不应超出186天");
        // }
        //设置每次查询条数
        // transferFlowDto.setPageSize(EXPORT_SIZE);
        // transferFlowDto.setRowCntPerPage(EXPORT_SIZE);

        List<FundNhouseTransFlowVo> queryResult = new ArrayList<>();
        boolean end = false;
        Page<FundNhouseTransFlowVo> page = new Page();

        ExcelWriter excelWriter = null;

        try {

            String fileNameTid = "sheet自定义名称";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setContentType("application/vnd.ms-excel; charset=utf-8");
            response.setCharacterEncoding("utf-8");
            idVo.setCreateEndTime(1631260545000L);
            idVo.setCreateEndTime(1631260945000L);
            String fileName = fileNameTid + "-" + sdf.format(DateUtil.longToDate(idVo.getCreateStartTime()))
                    + "-" + sdf.format(DateUtil.longToDate(idVo.getCreateEndTime()));
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8") + ".xlsx");

            /*
                这笔步骤的时候就是生成了表头了；表头的格式可以在这里边设置，也可以在FundNhouseTransFlowVo.java实体中用注解设置；
                    个人建议公用的在工具类类设置，不同导出文件不同的设置放在各自的实体中设置；
             */

            excelWriter = EasyExcelWriteUtils.getExcelWriterBuilder(response.getOutputStream(), FundNhouseTransFlowVo.class).build();
            WriteSheet writeSheet = EasyExcel.writerSheet(fileNameTid).build();

            while (!end) {
                // page = transPageList(transferFlowDto);
                //这里是假装查询
                page  = mockQuery();

                if (page.getTotalPage() == 0) {
                    throw new Exception("该时间段无交易流水");
                }
                if (Objects.equals(page.getPageNo(),page.getTotalPage()) || page.getTotalPage() == 0) {
                    end = true;
                }
                // transferFlowDto.setPageNo(transferFlowDto.getPageNo() + 1);  这里的作用是当前页数加1，下次循环就是查询下页了
                excelWriter.write(page.getList(), writeSheet);
                queryResult.clear();
                end = true;//手动种植循环
            }

        } catch (Exception e) {
            log.error("=======导出 新房商户流水异常=========", e);
            throw new RuntimeException(e.getMessage());
        } finally {
            if (excelWriter != null) {
                excelWriter.finish();
            }
            response.getOutputStream().flush();
            response.getOutputStream().close();
        }
    }
    @BincLog("test2方法")
    public void  test2() {
        log.info("----------test2----------");
    }

    @Override
    @BincLog("test3方法")
    public void  test3() {
        log.info("----------test3----------");
    }

    @Override
    @BincLog("test4方法")
    public void  test4() {
        log.info("----------test3----------");
    }

    @Autowired
    WechatPayImpl wechatPay;

    @Override
    @BincLog("自定义的输出")
    public ContractDto decode() throws IOException {
        ContractDto dto = ContractDto.builder().status(1).build();
        ContractDto decode = DictUtils.decode(dto);
        log.info(decode.toString());

        /**
         * 注解失效的场景
         */
        //掉用连个简单方法，看看注解否生效
        test2();  //调用本地方法
        test3();  //调用了同类中的方法，没有重新获取代理对象，注解失效  （这个使用起来更顺畅，因为有时候内容就是要在同一个实现类中的，硬要将代码分开写，就很奇怪；）
        IExportService bean = Global.getBean(IExportService.class);
        bean.test4(); //重新获取一下这个bean就行了；

        wechatPay.test5(); //或者调用零一个service的方法；

        return decode;

    }

    /*
        模拟查询过程，
            这里固定生成一个数据集合就够了
     */
    private Page<FundNhouseTransFlowVo> mockQuery() {
        Page<FundNhouseTransFlowVo> queryList = new Page<>();
        ArrayList<FundNhouseTransFlowVo> lists = Lists.newArrayList();
        for (int i = 0; i < 5 ; i++) {
            FundNhouseTransFlowVo build = FundNhouseTransFlowVo.builder()
                    .id(1L)
                    .tenantId(2L)
                    //2021-09-10 15:55:45
                    .createTm(1631260545000L)
                    .tradeNo(3L)
                    .orderId(4L)
                    .trnuid("第三方交易单号" + i)
                    .budgetType(1)
                    .budgetTypeStr("收入" + i)
                    .tranType(50)
                    .tranTypeStr("垫佣款" + i)
                    .accountId(5L)
                    .accountType(6)
                    .transferTranType(1)
                    .interBankStr("是" + i)
                    .fee(new BigDecimal(String.valueOf(12345.61)))
                    .amount(new BigDecimal(String.valueOf(78945.36)))
                    .interBank(7)
                    .merchantAmount(new BigDecimal(String.valueOf(222545.35)))
                    .customAccountType("商户" + i)
                    .merchantName("商户名称" + i)
                    .merchantId(8L)
                    .accttoBank("对方银行" + i)
                    .accttoBankdesc("对方开户行" + i)
                    .accttoCity("对方开户行城市" + i)
                    .accttoAcctid("对方账号" + i)
                    .accttoName("对方账户" + i)
                    .payStatus(9)
                    .tradeTm(1631260545000L)
                    .purpose("用款用途" + i)
                    .remark("备注" + i)
                    .build();
            lists.add(build);

        }
        queryList.setList(lists);
        queryList.setPageNo(1);
        queryList.setTotalRowCount(5L);
        return  queryList;
    }
}
